home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / fmopl.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  35KB  |  1,319 lines

  1. /*
  2. **
  3. ** File: fmopl.c -- software implementation of FM sound generator
  4. **
  5. ** Copyright (C) 1999 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
  6. **
  7. ** Version 0.36f
  8. **
  9. */
  10.  
  11. /*
  12.     preliminary :
  13.     Problem :
  14.     note:
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stdarg.h>
  21. #include <math.h>
  22. #include "driver.h"        /* use M.A.M.E. */
  23. #include "fmopl.h"
  24.  
  25. #ifndef PI
  26. #define PI 3.14159265358979323846
  27. #endif
  28.  
  29. /* -------------------- preliminary define section --------------------- */
  30. /* attack/decay rate time rate */
  31. #define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
  32. #define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
  33.  
  34. #define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
  35.  
  36. #define FREQ_BITS 24            /* frequency turn          */
  37.  
  38. /* counter bits = 20 , octerve 7 */
  39. #define FREQ_RATE   (1<<(FREQ_BITS-20))
  40. #define TL_BITS    (FREQ_BITS+2)
  41.  
  42. /* final output shift , limit minimum and maximum */
  43. #define OPL_OUTSB   (TL_BITS+3-16)        /* OPL output final shift 16bit */
  44. #define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
  45. #define OPL_MINOUT (-0x8000<<OPL_OUTSB)
  46.  
  47. /* -------------------- quality selection --------------------- */
  48.  
  49. /* sinwave entries */
  50. /* used static memory = SIN_ENT * 4 (byte) */
  51. #define SIN_ENT 2048
  52.  
  53. /* output level entries (envelope,sinwave) */
  54. /* envelope counter lower bits */
  55. #define ENV_BITS 16
  56. /* envelope output entries */
  57. #define EG_ENT   4096
  58. /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
  59. /* used static  memory = EG_ENT*4 (byte)                     */
  60.  
  61. #define EG_OFF   ((2*EG_ENT)<<ENV_BITS)  /* OFF          */
  62. #define EG_DED   EG_OFF
  63. #define EG_DST   (EG_ENT<<ENV_BITS)      /* DECAY  START */
  64. #define EG_AED   EG_DST
  65. #define EG_AST   0                       /* ATTACK START */
  66.  
  67. #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
  68.  
  69. /* LFO table entries */
  70. #define VIB_ENT 512
  71. #define VIB_SHIFT (32-9)
  72. #define AMS_ENT 512
  73. #define AMS_SHIFT (32-9)
  74.  
  75. #define VIB_RATE 256
  76.  
  77. /* -------------------- local defines , macros --------------------- */
  78.  
  79. /* register number to channel number , slot offset */
  80. #define SLOT1 0
  81. #define SLOT2 1
  82.  
  83. /* envelope phase */
  84. #define ENV_MOD_RR  0x00
  85. #define ENV_MOD_DR  0x01
  86. #define ENV_MOD_AR  0x02
  87.  
  88. /* -------------------- tables --------------------- */
  89. static const int slot_array[32]=
  90. {
  91.      0, 2, 4, 1, 3, 5,-1,-1,
  92.      6, 8,10, 7, 9,11,-1,-1,
  93.     12,14,16,13,15,17,-1,-1,
  94.     -1,-1,-1,-1,-1,-1,-1,-1
  95. };
  96.  
  97. /* key scale level */
  98. #define ML (0.1875*2/EG_STEP)
  99. static const UINT32 KSL_TABLE[8*16]=
  100. {
  101.     /* OCT 0 */
  102.      0.000*ML, 0.000*ML, 0.000*ML, 0.000*ML,
  103.      0.000*ML, 0.000*ML, 0.000*ML, 0.000*ML,
  104.      0.000*ML, 0.000*ML, 0.000*ML, 0.000*ML,
  105.      0.000*ML, 0.000*ML, 0.000*ML, 0.000*ML,
  106.     /* OCT 1 */
  107.      0.000*ML, 0.000*ML, 0.000*ML, 0.000*ML,
  108.      0.000*ML, 0.000*ML, 0.000*ML, 0.000*ML,
  109.      0.000*ML, 0.750*ML, 1.125*ML, 1.500*ML,
  110.      1.875*ML, 2.250*ML, 2.625*ML, 3.000*ML,
  111.     /* OCT 2 */
  112.      0.000*ML, 0.000*ML, 0.000*ML, 0.000*ML,
  113.      0.000*ML, 1.125*ML, 1.875*ML, 2.625*ML,
  114.      3.000*ML, 3.750*ML, 4.125*ML, 4.500*ML,
  115.      4.875*ML, 5.250*ML, 5.625*ML, 6.000*ML,
  116.     /* OCT 3 */
  117.      0.000*ML, 0.000*ML, 0.000*ML, 1.875*ML,
  118.      3.000*ML, 4.125*ML, 4.875*ML, 5.625*ML,
  119.      6.000*ML, 6.750*ML, 7.125*ML, 7.500*ML,
  120.      7.875*ML, 8.250*ML, 8.625*ML, 9.000*ML,
  121.     /* OCT 4 */
  122.      0.000*ML, 0.000*ML, 3.000*ML, 4.875*ML,
  123.      6.000*ML, 7.125*ML, 7.875*ML, 8.625*ML,
  124.      9.000*ML, 9.750*ML,10.125*ML,10.500*ML,
  125.     10.875*ML,11.250*ML,11.625*ML,12.000*ML,
  126.     /* OCT 5 */
  127.      0.000*ML, 3.000*ML, 6.000*ML, 7.875*ML,
  128.      9.000*ML,10.125*ML,10.875*ML,11.625*ML,
  129.     12.000*ML,12.750*ML,13.125*ML,13.500*ML,
  130.     13.875*ML,14.250*ML,14.625*ML,15.000*ML,
  131.     /* OCT 6 */
  132.      0.000*ML, 6.000*ML, 9.000*ML,10.875*ML,
  133.     12.000*ML,13.125*ML,13.875*ML,14.625*ML,
  134.     15.000*ML,15.750*ML,16.125*ML,16.500*ML,
  135.     16.875*ML,17.250*ML,17.625*ML,18.000*ML,
  136.     /* OCT 7 */
  137.      0.000*ML, 9.000*ML,12.000*ML,13.875*ML,
  138.     15.000*ML,16.125*ML,16.875*ML,17.625*ML,
  139.     18.000*ML,18.750*ML,19.125*ML,19.500*ML,
  140.     19.875*ML,20.250*ML,20.625*ML,21.000*ML
  141. };
  142. #undef ML
  143.  
  144. /* sustain lebel table (3db per step) */
  145. /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
  146. #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
  147. static const INT32 SL_TABLE[16]={
  148.  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
  149.  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
  150. };
  151. #undef SC
  152.  
  153. #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
  154. /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
  155. /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
  156. /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
  157. static INT32 *TL_TABLE;
  158.  
  159. /* pointers to TL_TABLE with sinwave output offset */
  160. static INT32 **SIN_TABLE;
  161.  
  162. /* LFO table */
  163. static INT32 *AMS_TABLE;
  164. static INT32 *VIB_TABLE;
  165.  
  166. /* envelope output curve table */
  167. /* attack + decay + OFF */
  168. static INT32 ENV_CURVE[2*EG_ENT+1];
  169.  
  170. /* multiple table */
  171. #define ML 2
  172. static const UINT32 MUL_TABLE[16]= {
  173. /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
  174.    0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
  175.    8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
  176. };
  177. #undef ML
  178.  
  179. /* dummy attack / decay rate ( when rate == 0 ) */
  180. static INT32 RATE_0[16]=
  181. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  182.  
  183. /* -------------------- static state --------------------- */
  184.  
  185. /* lock level of common table */
  186. static int num_lock = 0;
  187.  
  188. /* work table */
  189. static void *cur_chip = NULL;    /* current chip point */
  190. /* currenct chip state */
  191. /* static FMSAMPLE  *bufL,*bufR; */
  192. static OPL_CH *S_CH;
  193. static OPL_CH *E_CH;
  194. OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
  195.  
  196. static INT32 outd[1];
  197. static INT32 ams;
  198. static INT32 vib;
  199. INT32  *ams_table;
  200. INT32  *vib_table;
  201. static INT32 amsIncr;
  202. static INT32 vibIncr;
  203. static INT32 feedback2;        /* connect for SLOT 2 */
  204.  
  205. /* log output level */
  206. #define LOG_ERR  3      /* ERROR       */
  207. #define LOG_WAR  2      /* WARNING     */
  208. #define LOG_INF  1      /* INFORMATION */
  209.  
  210. #define LOG_LEVEL LOG_INF
  211.  
  212. #define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
  213.  
  214. /* --------------------- subroutines  --------------------- */
  215.  
  216. INLINE int Limit( int val, int max, int min ) {
  217.     if ( val > max )
  218.         val = max;
  219.     else if ( val < min )
  220.         val = min;
  221.  
  222.     return val;
  223. }
  224.  
  225. /* status set and IRQ handling */
  226. INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
  227. {
  228.     /* set status flag */
  229.     OPL->status |= flag;
  230.     if(!(OPL->status & 0x80))
  231.     {
  232.         if(OPL->status & OPL->statusmask)
  233.         {    /* IRQ on */
  234.             OPL->status |= 0x80;
  235.             /* callback user interrupt handler (IRQ is OFF to ON) */
  236.             if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
  237.         }
  238.     }
  239. }
  240.  
  241. /* status reset and IRQ handling */
  242. INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
  243. {
  244.     /* reset status flag */
  245.     OPL->status &=~flag;
  246.     if((OPL->status & 0x80))
  247.     {
  248.         if (!(OPL->status & OPL->statusmask) )
  249.         {
  250.             OPL->status &= 0x7f;
  251.             /* callback user interrupt handler (IRQ is ON to OFF) */
  252.             if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
  253.         }
  254.     }
  255. }
  256.  
  257. /* IRQ mask set */
  258. INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
  259. {
  260.     OPL->statusmask = flag;
  261.     /* IRQ handling check */
  262.     OPL_STATUS_SET(OPL,0);
  263.     OPL_STATUS_RESET(OPL,0);
  264. }
  265.  
  266. /* ----- key on  ----- */
  267. INLINE void OPL_KEYON(OPL_SLOT *SLOT)
  268. {
  269.     /* sin wave restart */
  270.     SLOT->Cnt = 0;
  271.     /* set attack */
  272.     SLOT->evm = ENV_MOD_AR;
  273.     SLOT->evs = SLOT->evsa;
  274.     SLOT->evc = EG_AST;
  275.     SLOT->eve = EG_AED;
  276. }
  277. /* ----- key off ----- */
  278. INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
  279. {
  280.     if( SLOT->evm > ENV_MOD_RR)
  281.     {
  282.         /* set envelope counter from envleope output */
  283.         SLOT->evm = ENV_MOD_RR;
  284.         if( !(SLOT->evc&EG_DST) )
  285.             //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
  286.             SLOT->evc = EG_DST;
  287.         SLOT->eve = EG_DED;
  288.         SLOT->evs = SLOT->evsr;
  289.     }
  290. }
  291.  
  292. /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
  293. /* return : envelope output */
  294. INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
  295. {
  296.     /* calcrate envelope generator */
  297.     if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
  298.     {
  299.         switch( SLOT->evm ){
  300.         case ENV_MOD_AR: /* ATTACK -> DECAY1 */
  301.             /* next DR */
  302.             SLOT->evm = ENV_MOD_DR;
  303.             SLOT->evc = EG_DST;
  304.             SLOT->eve = SLOT->SL;
  305.             SLOT->evs = SLOT->evsd;
  306.             break;
  307.         case ENV_MOD_DR: /* DECAY -> SL or RR */
  308.             SLOT->evc = SLOT->SL;
  309.             SLOT->eve = EG_DED;
  310.             if(SLOT->eg_typ)
  311.             {
  312.                 SLOT->evs = 0;
  313.             }
  314.             else
  315.             {
  316.                 SLOT->evm = ENV_MOD_RR;
  317.                 SLOT->evs = SLOT->evsr;
  318.             }
  319.             break;
  320.         case ENV_MOD_RR: /* RR -> OFF */
  321.             SLOT->evc = EG_OFF;
  322.             SLOT->eve = EG_OFF+1;
  323.             SLOT->evs = 0;
  324.             break;
  325.         }
  326.     }
  327.     /* calcrate envelope */
  328.     return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
  329. }
  330.  
  331. /* set algorythm connection */
  332. static void set_algorythm( OPL_CH *CH)
  333. {
  334.     INT32 *carrier = &outd[0];
  335.     CH->connect1 = CH->CON ? carrier : &feedback2;
  336.     CH->connect2 = carrier;
  337. }
  338.  
  339. /* ---------- frequency counter for operater update ---------- */
  340. INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
  341. {
  342.     int ksr;
  343.  
  344.     /* frequency step counter */
  345.     SLOT->Incr = CH->fc * SLOT->mul;
  346.     ksr = CH->kcode >> SLOT->KSR;
  347.  
  348.     if( SLOT->ksr != ksr )
  349.     {
  350.         SLOT->ksr = ksr;
  351.         /* attack , decay rate recalcration */
  352.         SLOT->evsa = SLOT->AR[ksr];
  353.         SLOT->evsd = SLOT->DR[ksr];
  354.         SLOT->evsr = SLOT->RR[ksr];
  355.     }
  356.     SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
  357. }
  358.  
  359. /* set multi,am,vib,EG-TYP,KSR,mul */
  360. INLINE void set_mul(FM_OPL *OPL,int slot,int v)
  361. {
  362.     OPL_CH   *CH   = &OPL->P_CH[slot/2];
  363.     OPL_SLOT *SLOT = &CH->SLOT[slot&1];
  364.  
  365.     SLOT->mul    = MUL_TABLE[v&0x0f];
  366.     SLOT->KSR    = (v&0x10) ? 0 : 2;
  367.     SLOT->eg_typ = (v&0x20)>>5;
  368.     SLOT->vib    = (v&0x40);
  369.     SLOT->ams    = (v&0x80);
  370.     CALC_FCSLOT(CH,SLOT);
  371. }
  372.  
  373. /* set ksl & tl */
  374. INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
  375. {
  376.     OPL_CH   *CH   = &OPL->P_CH[slot/2];
  377.     OPL_SLOT *SLOT = &CH->SLOT[slot&1];
  378.     int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
  379.  
  380.     SLOT->ksl = ksl ? 3-ksl : 31;
  381.     SLOT->TL  = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
  382.  
  383.     if( !(OPL->mode&0x80) )
  384.     {    /* not CSM latch total level */
  385.         SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
  386.     }
  387. }
  388.  
  389. /* set attack rate & decay rate  */
  390. INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
  391. {
  392.     OPL_CH   *CH   = &OPL->P_CH[slot/2];
  393.     OPL_SLOT *SLOT = &CH->SLOT[slot&1];
  394.     int ar = v>>4;
  395.     int dr = v&0x0f;
  396.  
  397.     SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
  398.     SLOT->evsa = SLOT->AR[SLOT->ksr];
  399.     if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
  400.  
  401.     SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
  402.     SLOT->evsd = SLOT->DR[SLOT->ksr];
  403.     if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
  404. }
  405.  
  406. /* set sustain level & release rate */
  407. INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
  408. {
  409.     OPL_CH   *CH   = &OPL->P_CH[slot/2];
  410.     OPL_SLOT *SLOT = &CH->SLOT[slot&1];
  411.     int sl = v>>4;
  412.     int rr = v & 0x0f;
  413.  
  414.     SLOT->SL = SL_TABLE[sl];
  415.     if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
  416.     SLOT->RR = &OPL->DR_TABLE[rr<<2];
  417.     SLOT->evsr = SLOT->RR[SLOT->ksr];
  418.     if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
  419. }
  420.  
  421. /* operator output calcrator */
  422. #define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
  423. /* ---------- calcrate one of channel ---------- */
  424. INLINE void OPL_CALC_CH( OPL_CH *CH )
  425. {
  426.     UINT32 env_out;
  427.     OPL_SLOT *SLOT;
  428.  
  429.     feedback2 = 0;
  430.     /* SLOT 1 */
  431.     SLOT = &CH->SLOT[SLOT1];
  432.     env_out=OPL_CALC_SLOT(SLOT);
  433.     if( env_out < EG_ENT-1 )
  434.     {
  435.         /* PG */
  436.         if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
  437.         else          SLOT->Cnt += SLOT->Incr;
  438.         /* connectoion */
  439.         if(CH->FB)
  440.         {
  441.             int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
  442.             CH->op1_out[1] = CH->op1_out[0];
  443.             *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
  444.         }
  445.         else
  446.         {
  447.             *CH->connect1 += OP_OUT(SLOT,env_out,0);
  448.         }
  449.     }else
  450.     {
  451.         CH->op1_out[1] = CH->op1_out[0];
  452.         CH->op1_out[0] = 0;
  453.     }
  454.     /* SLOT 2 */
  455.     SLOT = &CH->SLOT[SLOT2];
  456.     env_out=OPL_CALC_SLOT(SLOT);
  457.     if( env_out < EG_ENT-1 )
  458.     {
  459.         /* PG */
  460.         if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
  461.         else          SLOT->Cnt += SLOT->Incr;
  462.         /* connectoion */
  463.         outd[0] += OP_OUT(SLOT,env_out, feedback2);
  464.     }
  465. }
  466.  
  467. /* ---------- calcrate rythm block ---------- */
  468. #define WHITE_NOISE_db 6.0
  469. INLINE void OPL_CALC_RH( OPL_CH *CH )
  470. {
  471.     UINT32 env_tam,env_sd,env_top,env_hh;
  472.     int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
  473.     INT32 tone8;
  474.  
  475.     OPL_SLOT *SLOT;
  476.     int env_out;
  477.  
  478.     /* BD : same as FM serial mode and output level is large */
  479.     feedback2 = 0;
  480.     /* SLOT 1 */
  481.     SLOT = &CH[6].SLOT[SLOT1];
  482.     env_out=OPL_CALC_SLOT(SLOT);
  483.     if( env_out < EG_ENT-1 )
  484.     {
  485.         /* PG */
  486.         if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
  487.         else          SLOT->Cnt += SLOT->Incr;
  488.         /* connectoion */
  489.         if(CH[6].FB)
  490.         {
  491.             int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
  492.             CH[6].op1_out[1] = CH[6].op1_out[0];
  493.             feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
  494.         }
  495.         else
  496.         {
  497.             feedback2 = OP_OUT(SLOT,env_out,0);
  498.         }
  499.     }else
  500.     {
  501.         feedback2 = 0;
  502.         CH[6].op1_out[1] = CH[6].op1_out[0];
  503.         CH[6].op1_out[0] = 0;
  504.     }
  505.     /* SLOT 2 */
  506.     SLOT = &CH[6].SLOT[SLOT2];
  507.     env_out=OPL_CALC_SLOT(SLOT);
  508.     if( env_out < EG_ENT-1 )
  509.     {
  510.         /* PG */
  511.         if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
  512.         else          SLOT->Cnt += SLOT->Incr;
  513.         /* connectoion */
  514.         outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
  515.     }
  516.  
  517.     // SD  (17) = mul14[fnum7] + white noise
  518.     // TAM (15) = mul15[fnum8]
  519.     // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
  520.     // HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
  521.     env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
  522.     env_tam=OPL_CALC_SLOT(SLOT8_1);
  523.     env_top=OPL_CALC_SLOT(SLOT8_2);
  524.     env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
  525.  
  526.     /* PG */
  527.     if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
  528.     else             SLOT7_1->Cnt += 2*SLOT7_1->Incr;
  529.     if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
  530.     else             SLOT7_2->Cnt += (CH[7].fc*8);
  531.     if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
  532.     else             SLOT8_1->Cnt += SLOT8_1->Incr;
  533.     if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
  534.     else             SLOT8_2->Cnt += (CH[8].fc*48);
  535.  
  536.     tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
  537.  
  538.     /* SD */
  539.     if( env_sd < EG_ENT-1 )
  540.         outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
  541.     /* TAM */
  542.     if( env_tam < EG_ENT-1 )
  543.         outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
  544.     /* TOP-CY */
  545.     if( env_top < EG_ENT-1 )
  546.         outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
  547.     /* HH */
  548.     if( env_hh  < EG_ENT-1 )
  549.         outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
  550. }
  551.  
  552. /* ----------- initialize time tabls ----------- */
  553. static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
  554. {
  555.     int i;
  556.     double rate;
  557.  
  558.     /* make attack rate & decay rate tables */
  559.     for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
  560.     for (i = 4;i <= 60;i++){
  561.         rate  = OPL->freqbase;                        /* frequency rate */
  562.         if( i < 60 ) rate *= 1.0+(i&3)*0.25;        /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
  563.         rate *= 1<<((i>>2)-1);                        /* b2-5 : shift bit */
  564.         rate *= (double)(EG_ENT<<ENV_BITS);
  565.         OPL->AR_TABLE[i] = rate / ARRATE;
  566.         OPL->DR_TABLE[i] = rate / DRRATE;
  567.     }
  568.     for (i = 60;i < 76;i++)
  569.     {
  570.         OPL->AR_TABLE[i] = EG_AED-1;
  571.         OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
  572.     }
  573. #if 0
  574.     for (i = 0;i < 64 ;i++){    /* make for overflow area */
  575.         LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
  576.             ((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
  577.             ((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
  578.     }
  579. #endif
  580. }
  581.  
  582. /* ---------- generic table initialize ---------- */
  583. static int OPLOpenTable( void )
  584. {
  585.     int s,t;
  586.     double rate;
  587.     int i,j;
  588.     double pom;
  589.  
  590.     /* allocate dynamic tables */
  591.     if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
  592.         return 0;
  593.     if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
  594.     {
  595.         free(TL_TABLE);
  596.         return 0;
  597.     }
  598.     if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
  599.     {
  600.         free(TL_TABLE);
  601.         free(SIN_TABLE);
  602.         return 0;
  603.     }
  604.     if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
  605.     {
  606.         free(TL_TABLE);
  607.         free(SIN_TABLE);
  608.         free(AMS_TABLE);
  609.         return 0;
  610.     }
  611.     /* make total level table */
  612.     for (t = 0;t < EG_ENT-1 ;t++){
  613.         rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);    /* dB -> voltage */
  614.         TL_TABLE[       t] =  (int)rate;
  615.         TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
  616. /*        LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
  617.     }
  618.     /* fill volume off area */
  619.     for ( t = EG_ENT-1; t < TL_MAX ;t++){
  620.         TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
  621.     }
  622.  
  623.     /* make sinwave table (total level offet) */
  624.     /* degree 0 = degree 180                   = off */
  625.     SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2]         = &TL_TABLE[EG_ENT-1];
  626.     for (s = 1;s <= SIN_ENT/4;s++){
  627.         pom = sin(2*PI*s/SIN_ENT); /* sin     */
  628.         pom = 20*log10(1/pom);       /* decibel */
  629.         j = pom / EG_STEP;         /* TL_TABLE steps */
  630.  
  631.         /* degree 0   -  90    , degree 180 -  90 : plus section */
  632.         SIN_TABLE[          s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
  633.         /* degree 180 - 270    , degree 360 - 270 : minus section */
  634.         SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT  -s] = &TL_TABLE[TL_MAX+j];
  635. /*        LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
  636.     }
  637.     for (s = 0;s < SIN_ENT;s++)
  638.     {
  639.         SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
  640.         SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
  641.         SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
  642.     }
  643.  
  644.     /* envelope counter -> envelope output table */
  645.     for (i=0; i<EG_ENT; i++)
  646.     {
  647.         /* ATTACK curve */
  648.         pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
  649.         /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
  650.         ENV_CURVE[i] = (int)pom;
  651.         /* DECAY ,RELEASE curve */
  652.         ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
  653.     }
  654.     /* off */
  655.     ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
  656.     /* make LFO ams table */
  657.     for (i=0; i<AMS_ENT; i++)
  658.     {
  659.         pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
  660.         AMS_TABLE[i]         = (1.0/EG_STEP)*pom; /* 1dB   */
  661.         AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
  662.     }
  663.     /* make LFO vibrate table */
  664.     for (i=0; i<VIB_ENT; i++)
  665.     {
  666.         /* 100cent = 1seminote = 6% ?? */
  667.         pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
  668.         VIB_TABLE[i]         = VIB_RATE + (pom*0.07); /* +- 7cent */
  669.         VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
  670.         /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
  671.     }
  672.     return 1;
  673. }
  674.  
  675.  
  676. static void OPLCloseTable( void )
  677. {
  678.     free(TL_TABLE);
  679.     free(SIN_TABLE);
  680.     free(AMS_TABLE);
  681.     free(VIB_TABLE);
  682. }
  683.  
  684. /* CSM Key Controll */
  685. INLINE void CSMKeyControll(OPL_CH *CH)
  686. {
  687.     OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
  688.     OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
  689.     /* all key off */
  690.     OPL_KEYOFF(slot1);
  691.     OPL_KEYOFF(slot2);
  692.     /* total level latch */
  693.     slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
  694.     slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
  695.     /* key on */
  696.     CH->op1_out[0] = CH->op1_out[1] = 0;
  697.     OPL_KEYON(slot1);
  698.     OPL_KEYON(slot2);
  699. }
  700.  
  701. /* ---------- opl initialize ---------- */
  702. static void OPL_initalize(FM_OPL *OPL)
  703. {
  704.     int fn;
  705.  
  706.     /* frequency base */
  707.     OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72  : 0;
  708.     /* Timer base time */
  709.     OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
  710.     /* make time tables */
  711.     init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
  712.     /* make fnumber -> increment counter table */
  713.     for( fn=0 ; fn < 1024 ; fn++ )
  714.     {
  715.         OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
  716.     }
  717.     /* LFO freq.table */
  718.     OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
  719.     OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
  720. }
  721.  
  722. /* ---------- write a OPL registers ---------- */
  723. static void OPLWriteReg(FM_OPL *OPL, int r, int v)
  724. {
  725.     OPL_CH *CH;
  726.     int slot;
  727.     int block_fnum;
  728.  
  729.     switch(r&0xe0)
  730.     {
  731.     case 0x00: /* 00-1f:controll */
  732.         switch(r&0x1f)
  733.         {
  734.         case 0x01:
  735.             /* wave selector enable */
  736.             if(OPL->type&OPL_TYPE_WAVESEL)
  737.             {
  738.                 OPL->wavesel = v&0x20;
  739.                 if(!OPL->wavesel)
  740.                 {
  741.                     /* preset compatible mode */
  742.                     int c;
  743.                     for(c=0;c<OPL->max_ch;c++)
  744.                     {
  745.                         OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
  746.                         OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
  747.                     }
  748.                 }
  749.             }
  750.             return;
  751.         case 0x02:    /* Timer 1 */
  752.             OPL->T[0] = (256-v)*4;
  753.             break;
  754.         case 0x03:    /* Timer 2 */
  755.             OPL->T[1] = (256-v)*16;
  756.             return;
  757.         case 0x04:    /* IRQ clear / mask and Timer enable */
  758.             if(v&0x80)
  759.             {    /* IRQ flag clear */
  760.                 OPL_STATUS_RESET(OPL,0x7f);
  761.             }
  762.             else
  763.             {    /* set IRQ mask ,timer enable*/
  764.                 UINT8 st1 = v&1;
  765.                 UINT8 st2 = (v>>1)&1;
  766.                 /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
  767.                 OPL_STATUS_RESET(OPL,v&0x78);
  768.                 OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
  769.                 /* timer 2 */
  770.                 if(OPL->st[1] != st2)
  771.                 {
  772.                     double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
  773.                     OPL->st[1] = st2;
  774.                     if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
  775.                 }
  776.                 /* timer 1 */
  777.                 if(OPL->st[0] != st1)
  778.                 {
  779.                     double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
  780.                     OPL->st[0] = st1;
  781.                     if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
  782.                 }
  783.             }
  784.             return;
  785. #if BUILD_Y8950
  786.         case 0x06:        /* Key Board OUT */
  787.             if(OPL->type&OPL_TYPE_KEYBOARD)
  788.             {
  789.                 if(OPL->keyboardhandler_w)
  790.                     OPL->keyboardhandler_w(OPL->keyboard_param,v);
  791.                 else
  792.                     LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
  793.             }
  794.             return;
  795.         case 0x07:    /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
  796.             if(OPL->type&OPL_TYPE_ADPCM)
  797.                 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
  798.             return;
  799.         case 0x08:    /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
  800.             OPL->mode = v;
  801.             v&=0x1f;    /* for DELTA-T unit */
  802.         case 0x09:        /* START ADD */
  803.         case 0x0a:
  804.         case 0x0b:        /* STOP ADD  */
  805.         case 0x0c:
  806.         case 0x0d:        /* PRESCALE   */
  807.         case 0x0e:
  808.         case 0x0f:        /* ADPCM data */
  809.         case 0x10:         /* DELTA-N    */
  810.         case 0x11:         /* DELTA-N    */
  811.         case 0x12:         /* EG-CTRL    */
  812.             if(OPL->type&OPL_TYPE_ADPCM)
  813.                 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
  814.             return;
  815. #if 0
  816.         case 0x15:        /* DAC data    */
  817.         case 0x16:
  818.         case 0x17:        /* SHIFT    */
  819.             return;
  820.         case 0x18:        /* I/O CTRL (Direction) */
  821.             if(OPL->type&OPL_TYPE_IO)
  822.                 OPL->portDirection = v&0x0f;
  823.             return;
  824.         case 0x19:        /* I/O DATA */
  825.             if(OPL->type&OPL_TYPE_IO)
  826.             {
  827.                 OPL->portLatch = v;
  828.                 if(OPL->porthandler_w)
  829.                     OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
  830.             }
  831.             return;
  832.         case 0x1a:        /* PCM data */
  833.             return;
  834. #endif
  835. #endif
  836.         }
  837.         break;
  838.     case 0x20:    /* am,vib,ksr,eg type,mul */
  839.         slot = slot_array[r&0x1f];
  840.         if(slot == -1) return;
  841.         set_mul(OPL,slot,v);
  842.         return;
  843.     case 0x40:
  844.         slot = slot_array[r&0x1f];
  845.         if(slot == -1) return;
  846.         set_ksl_tl(OPL,slot,v);
  847.         return;
  848.     case 0x60:
  849.         slot = slot_array[r&0x1f];
  850.         if(slot == -1) return;
  851.         set_ar_dr(OPL,slot,v);
  852.         return;
  853.     case 0x80:
  854.         slot = slot_array[r&0x1f];
  855.         if(slot == -1) return;
  856.         set_sl_rr(OPL,slot,v);
  857.         return;
  858.     case 0xa0:
  859.         switch(r)
  860.         {
  861.         case 0xbd:
  862.             /* amsep,vibdep,r,bd,sd,tom,tc,hh */
  863.             {
  864.             UINT8 rkey = OPL->rythm^v;
  865.             OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
  866.             OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
  867.             OPL->rythm  = v&0x3f;
  868.             if(OPL->rythm&0x20)
  869.             {
  870. #if 0
  871.                 usrintf_showmessage("OPL Rythm mode select");
  872. #endif
  873.                 /* BD key on/off */
  874.                 if(rkey&0x10)
  875.                 {
  876.                     if(v&0x10)
  877.                     {
  878.                         OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
  879.                         OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
  880.                         OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
  881.                     }
  882.                     else
  883.                     {
  884.                         OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
  885.                         OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
  886.                     }
  887.                 }
  888.                 /* SD key on/off */
  889.                 if(rkey&0x08)
  890.                 {
  891.                     if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
  892.                     else       OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
  893.                 }/* TAM key on/off */
  894.                 if(rkey&0x04)
  895.                 {
  896.                     if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
  897.                     else       OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
  898.                 }
  899.                 /* TOP-CY key on/off */
  900.                 if(rkey&0x02)
  901.                 {
  902.                     if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
  903.                     else       OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
  904.                 }
  905.                 /* HH key on/off */
  906.                 if(rkey&0x01)
  907.                 {
  908.                     if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
  909.                     else       OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
  910.                 }
  911.             }
  912.             }
  913.             return;
  914.         }
  915.         /* keyon,block,fnum */
  916.         if( (r&0x0f) > 8) return;
  917.         CH = &OPL->P_CH[r&0x0f];
  918.         if(!(r&0x10))
  919.         {    /* a0-a8 */
  920.             block_fnum  = (CH->block_fnum&0x1f00) | v;
  921.         }
  922.         else
  923.         {    /* b0-b8 */
  924.             int keyon = (v>>5)&1;
  925.             block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
  926.             if(CH->keyon != keyon)
  927.             {
  928.                 if( (CH->keyon=keyon) )
  929.                 {
  930.                     CH->op1_out[0] = CH->op1_out[1] = 0;
  931.                     OPL_KEYON(&CH->SLOT[SLOT1]);
  932.                     OPL_KEYON(&CH->SLOT[SLOT2]);
  933.                 }
  934.                 else
  935.                 {
  936.                     OPL_KEYOFF(&CH->SLOT[SLOT1]);
  937.                     OPL_KEYOFF(&CH->SLOT[SLOT2]);
  938.                 }
  939.             }
  940.         }
  941.         /* update */
  942.         if(CH->block_fnum != block_fnum)
  943.         {
  944.             int blockRv = 7-(block_fnum>>10);
  945.             int fnum   = block_fnum&0x3ff;
  946.             CH->block_fnum = block_fnum;
  947.  
  948.             CH->ksl_base = KSL_TABLE[block_fnum>>6];
  949.             CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
  950.             CH->kcode = CH->block_fnum>>9;
  951.             if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
  952.             CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
  953.             CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
  954.         }
  955.         return;
  956.     case 0xc0:
  957.         /* FB,C */
  958.         if( (r&0x0f) > 8) return;
  959.         CH = &OPL->P_CH[r&0x0f];
  960.         {
  961.         int feedback = (v>>1)&7;
  962.         CH->FB   = feedback ? (8+1) - feedback : 0;
  963.         CH->CON = v&1;
  964.         set_algorythm(CH);
  965.         }
  966.         return;
  967.     case 0xe0: /* wave type */
  968.         slot = slot_array[r&0x1f];
  969.         if(slot == -1) return;
  970.         CH = &OPL->P_CH[slot/2];
  971.         if(OPL->wavesel)
  972.         {
  973.             /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
  974.             CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
  975.         }
  976.         return;
  977.     }
  978. }
  979.  
  980. /* lock/unlock for common table */
  981. static int OPL_LockTable(void)
  982. {
  983.     num_lock++;
  984.     if(num_lock>1) return 0;
  985.     /* first time */
  986.     cur_chip = NULL;
  987.     /* allocate total level table (128kb space) */
  988.     if( !OPLOpenTable() )
  989.     {
  990.         num_lock--;
  991.         return -1;
  992.     }
  993.     return 0;
  994. }
  995.  
  996. static void OPL_UnLockTable(void)
  997. {
  998.     if(num_lock) num_lock--;
  999.     if(num_lock) return;
  1000.     /* last time */
  1001.     cur_chip = NULL;
  1002.     OPLCloseTable();
  1003. }
  1004.  
  1005. #if (BUILD_YM3812 || BUILD_YM3526)
  1006. /*******************************************************************************/
  1007. /*        YM3812 local section                                                   */
  1008. /*******************************************************************************/
  1009.  
  1010. /* ---------- update one of chip ----------- */
  1011. void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
  1012. {
  1013.     int i;
  1014.     int data;
  1015.     FMSAMPLE *buf = buffer;
  1016.     UINT32 amsCnt  = OPL->amsCnt;
  1017.     UINT32 vibCnt  = OPL->vibCnt;
  1018.     UINT8 rythm = OPL->rythm&0x20;
  1019.     OPL_CH *CH,*R_CH;
  1020.  
  1021.     if( (void *)OPL != cur_chip ){
  1022.         cur_chip = (void *)OPL;
  1023.         /* channel pointers */
  1024.         S_CH = OPL->P_CH;
  1025.         E_CH = &S_CH[9];
  1026.         /* rythm slot */
  1027.         SLOT7_1 = &S_CH[7].SLOT[SLOT1];
  1028.         SLOT7_2 = &S_CH[7].SLOT[SLOT2];
  1029.         SLOT8_1 = &S_CH[8].SLOT[SLOT1];
  1030.         SLOT8_2 = &S_CH[8].SLOT[SLOT2];
  1031.         /* LFO state */
  1032.         amsIncr = OPL->amsIncr;
  1033.         vibIncr = OPL->vibIncr;
  1034.         ams_table = OPL->ams_table;
  1035.         vib_table = OPL->vib_table;
  1036.     }
  1037.     R_CH = rythm ? &S_CH[6] : E_CH;
  1038.     for( i=0; i < length ; i++ )
  1039.     {
  1040.         /*            channel A         channel B         channel C      */
  1041.         /* LFO */
  1042.         ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
  1043.         vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
  1044.         outd[0] = 0;
  1045.         /* FM part */
  1046.         for(CH=S_CH ; CH < R_CH ; CH++)
  1047.             OPL_CALC_CH(CH);
  1048.         /* Rythn part */
  1049.         if(rythm)
  1050.             OPL_CALC_RH(S_CH);
  1051.         /* limit check */
  1052.         data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
  1053.         /* store to sound buffer */
  1054.         buf[i] = data >> OPL_OUTSB;
  1055.     }
  1056.  
  1057.     OPL->amsCnt = amsCnt;
  1058.     OPL->vibCnt = vibCnt;
  1059. }
  1060. #endif /* (BUILD_YM3812 || BUILD_YM3526) */
  1061.  
  1062. #if BUILD_Y8950
  1063.  
  1064. void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
  1065. {
  1066.     int i;
  1067.     int data;
  1068.     FMSAMPLE *buf = buffer;
  1069.     UINT32 amsCnt  = OPL->amsCnt;
  1070.     UINT32 vibCnt  = OPL->vibCnt;
  1071.     UINT8 rythm = OPL->rythm&0x20;
  1072.     OPL_CH *CH,*R_CH;
  1073.     YM_DELTAT *DELTAT = OPL->deltat;
  1074.  
  1075.     /* setup DELTA-T unit */
  1076.     YM_DELTAT_DECODE_PRESET(DELTAT);
  1077.  
  1078.     if( (void *)OPL != cur_chip ){
  1079.         cur_chip = (void *)OPL;
  1080.         /* channel pointers */
  1081.         S_CH = OPL->P_CH;
  1082.         E_CH = &S_CH[9];
  1083.         /* rythm slot */
  1084.         SLOT7_1 = &S_CH[7].SLOT[SLOT1];
  1085.         SLOT7_2 = &S_CH[7].SLOT[SLOT2];
  1086.         SLOT8_1 = &S_CH[8].SLOT[SLOT1];
  1087.         SLOT8_2 = &S_CH[8].SLOT[SLOT2];
  1088.         /* LFO state */
  1089.         amsIncr = OPL->amsIncr;
  1090.         vibIncr = OPL->vibIncr;
  1091.         ams_table = OPL->ams_table;
  1092.         vib_table = OPL->vib_table;
  1093.     }
  1094.     R_CH = rythm ? &S_CH[6] : E_CH;
  1095.     for( i=0; i < length ; i++ )
  1096.     {
  1097.         /*            channel A         channel B         channel C      */
  1098.         /* LFO */
  1099.         ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
  1100.         vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
  1101.         outd[0] = 0;
  1102.         /* deltaT ADPCM */
  1103.         if( DELTAT->flag )
  1104.             YM_DELTAT_ADPCM_CALC(DELTAT);
  1105.         /* FM part */
  1106.         for(CH=S_CH ; CH < R_CH ; CH++)
  1107.             OPL_CALC_CH(CH);
  1108.         /* Rythn part */
  1109.         if(rythm)
  1110.             OPL_CALC_RH(S_CH);
  1111.         /* limit check */
  1112.         data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
  1113.         /* store to sound buffer */
  1114.         buf[i] = data >> OPL_OUTSB;
  1115.     }
  1116.     OPL->amsCnt = amsCnt;
  1117.     OPL->vibCnt = vibCnt;
  1118.     /* deltaT START flag */
  1119.     if( !DELTAT->flag )
  1120.         OPL->status &= 0xfe;
  1121. }
  1122. #endif
  1123.  
  1124. /* ---------- reset one of chip ---------- */
  1125. void OPLResetChip(FM_OPL *OPL)
  1126. {
  1127.     int c,s;
  1128.     int i;
  1129.  
  1130.     /* reset chip */
  1131.     OPL->mode   = 0;    /* normal mode */
  1132.     OPL_STATUS_RESET(OPL,0x7f);
  1133.     /* reset with register write */
  1134.     OPLWriteReg(OPL,0x01,0); /* wabesel disable */
  1135.     OPLWriteReg(OPL,0x02,0); /* Timer1 */
  1136.     OPLWriteReg(OPL,0x03,0); /* Timer2 */
  1137.     OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
  1138.     for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
  1139.     /* reset OPerator paramater */
  1140.     for( c = 0 ; c < OPL->max_ch ; c++ )
  1141.     {
  1142.         OPL_CH *CH = &OPL->P_CH[c];
  1143.         /* OPL->P_CH[c].PAN = OPN_CENTER; */
  1144.         for(s = 0 ; s < 2 ; s++ )
  1145.         {
  1146.             /* wave table */
  1147.             CH->SLOT[s].wavetable = &SIN_TABLE[0];
  1148.             /* CH->SLOT[s].evm = ENV_MOD_RR; */
  1149.             CH->SLOT[s].evc = EG_OFF;
  1150.             CH->SLOT[s].eve = EG_OFF+1;
  1151.             CH->SLOT[s].evs = 0;
  1152.         }
  1153.     }
  1154. #if BUILD_Y8950
  1155.     if(OPL->type&OPL_TYPE_ADPCM)
  1156.     {
  1157.         YM_DELTAT *DELTAT = OPL->deltat;
  1158.  
  1159.         DELTAT->freqbase = OPL->freqbase;
  1160.         DELTAT->output_pointer = outd;
  1161.         DELTAT->portshift = 5;
  1162.         DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
  1163.         YM_DELTAT_ADPCM_Reset(DELTAT,0);
  1164.     }
  1165. #endif
  1166. }
  1167.  
  1168. /* ----------  Create one of vietual YM3812 ----------       */
  1169. /* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
  1170. FM_OPL *OPLCreate(int type, int clock, int rate)
  1171. {
  1172.     char *ptr;
  1173.     FM_OPL *OPL;
  1174.     int state_size;
  1175.     int max_ch = 9; /* normaly 9 channels */
  1176.  
  1177.     if( OPL_LockTable() ==-1) return NULL;
  1178.     /* allocate OPL state space */
  1179.     state_size  = sizeof(FM_OPL);
  1180.     state_size += sizeof(OPL_CH)*max_ch;
  1181. #if BUILD_Y8950
  1182.     if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
  1183. #endif
  1184.     /* allocate memory block */
  1185.     ptr = malloc(state_size);
  1186.     if(ptr==NULL) return NULL;
  1187.     /* clear */
  1188.     memset(ptr,0,state_size);
  1189.     OPL        = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
  1190.     OPL->P_CH  = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
  1191. #if BUILD_Y8950
  1192.     if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
  1193. #endif
  1194.     /* set channel state pointer */
  1195.     OPL->type  = type;
  1196.     OPL->clock = clock;
  1197.     OPL->rate  = rate;
  1198.     OPL->max_ch = max_ch;
  1199.     /* init grobal tables */
  1200.     OPL_initalize(OPL);
  1201.     /* reset chip */
  1202.     OPLResetChip(OPL);
  1203.     return OPL;
  1204. }
  1205.  
  1206. /* ----------  Destroy one of vietual YM3812 ----------       */
  1207. void OPLDestroy(FM_OPL *OPL)
  1208. {
  1209.     OPL_UnLockTable();
  1210.     free(OPL);
  1211. }
  1212.  
  1213. /* ----------  Option handlers ----------       */
  1214.  
  1215. void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
  1216. {
  1217.     OPL->TimerHandler   = TimerHandler;
  1218.     OPL->TimerParam = channelOffset;
  1219. }
  1220. void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
  1221. {
  1222.     OPL->IRQHandler     = IRQHandler;
  1223.     OPL->IRQParam = param;
  1224. }
  1225. void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
  1226. {
  1227.     OPL->UpdateHandler = UpdateHandler;
  1228.     OPL->UpdateParam = param;
  1229. }
  1230. #if BUILD_Y8950
  1231. void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
  1232. {
  1233.     OPL->porthandler_w = PortHandler_w;
  1234.     OPL->porthandler_r = PortHandler_r;
  1235.     OPL->port_param = param;
  1236. }
  1237.  
  1238. void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
  1239. {
  1240.     OPL->keyboardhandler_w = KeyboardHandler_w;
  1241.     OPL->keyboardhandler_r = KeyboardHandler_r;
  1242.     OPL->keyboard_param = param;
  1243. }
  1244. #endif
  1245. /* ---------- YM3812 I/O interface ---------- */
  1246. int OPLWrite(FM_OPL *OPL,int a,int v)
  1247. {
  1248.     if( !(a&1) )
  1249.     {    /* address port */
  1250.         OPL->address = v & 0xff;
  1251.     }
  1252.     else
  1253.     {    /* data port */
  1254.         if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
  1255.         OPLWriteReg(OPL,OPL->address,v);
  1256.     }
  1257.     return OPL->status>>7;
  1258. }
  1259.  
  1260. unsigned char OPLRead(FM_OPL *OPL,int a)
  1261. {
  1262.     if( !(a&1) )
  1263.     {    /* status port */
  1264.         return OPL->status & (OPL->statusmask|0x80);
  1265.     }
  1266.     /* data port */
  1267.     switch(OPL->address)
  1268.     {
  1269.     case 0x05: /* KeyBoard IN */
  1270.         if(OPL->type&OPL_TYPE_KEYBOARD)
  1271.         {
  1272.             if(OPL->keyboardhandler_r)
  1273.                 return OPL->keyboardhandler_r(OPL->keyboard_param);
  1274.             else
  1275.                 LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
  1276.         }
  1277.         return 0;
  1278. #if 0
  1279.     case 0x0f: /* ADPCM-DATA  */
  1280.         return 0;
  1281. #endif
  1282.     case 0x19: /* I/O DATA    */
  1283.         if(OPL->type&OPL_TYPE_IO)
  1284.         {
  1285.             if(OPL->porthandler_r)
  1286.                 return OPL->porthandler_r(OPL->port_param);
  1287.             else
  1288.                 LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
  1289.         }
  1290.         return 0;
  1291.     case 0x1a: /* PCM-DATA    */
  1292.         return 0;
  1293.     }
  1294.     return 0;
  1295. }
  1296.  
  1297. int OPLTimerOver(FM_OPL *OPL,int c)
  1298. {
  1299.     if( c )
  1300.     {    /* Timer B */
  1301.         OPL_STATUS_SET(OPL,0x20);
  1302.     }
  1303.     else
  1304.     {    /* Timer A */
  1305.         OPL_STATUS_SET(OPL,0x40);
  1306.         /* CSM mode key,TL controll */
  1307.         if( OPL->mode & 0x80 )
  1308.         {    /* CSM mode total level latch and auto key on */
  1309.             int ch;
  1310.             if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
  1311.             for(ch=0;ch<9;ch++)
  1312.                 CSMKeyControll( &OPL->P_CH[ch] );
  1313.         }
  1314.     }
  1315.     /* reload timer */
  1316.     if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
  1317.     return OPL->status>>7;
  1318. }
  1319.